package concurrency;

import java.util.concurrent.TimeUnit;

/**
 * Using a named inner class
 */
class InnerThread1 {
    private int mCountDown = 5;

    private Inner mInner;

    /**
     * InnerThread1创建了一个继承Thread的内部类
     * 在构造器创建了这个内部类的一个实例
     */
    public InnerThread1(String name) {
        mInner = new Inner(name);
    }

    private class Inner extends Thread {
        Inner(String name) {
            super(name);
            start();
        }

        public void run() {
            try {
                while(true) {
                    System.out.println(this);
                    if(--mCountDown == 0) {
                        return;
                    }
                    sleep(10);
                }
            } catch(InterruptedException e) {
                System.out.println("interrupted");
            }
        }

        public String toString() {
            return getName() + ": " + mCountDown;
        }
    }
}

/**
 * Using an anonymous inner class:
 */
class InnerThread2 {
    private int mCountDown = 5;

    private Thread mThread;

    public InnerThread2(String name) {
        // 在构造器创建一个匿名的Thread子类，并且将其向上
        // 转型为Thread引用mThread。
        mThread = new Thread(name) {
            public void run() {
                try {
                    while(true) {
                        System.out.println(this);
                        if(--mCountDown == 0) {
                            return;
                        }
                        sleep(10);
                    }
                } catch(InterruptedException e) {
                    System.out.println("sleep() interrupted");
                }
            }

            public String toString() {
                return getName() + ": " + mCountDown;
            }
        };

        mThread.start();
    }
}

/**
 * Using a named Runnable implementation
 */
class InnerRunnable1 {
    private int mCountDown = 5;

    private Inner mInner;

    private class Inner implements Runnable {
        Thread mThread;

        Inner(String name) {
            mThread = new Thread(this, name); // 注意这个this，是将启动本次任务
            mThread.start();
        }

        public void run() {
            try {
                while(true) {
                    System.out.println(this);
                    if(--mCountDown == 0) {
                        return;
                    }
                    TimeUnit.MILLISECONDS.sleep(10);
                }
            } catch(InterruptedException e) {
                System.out.println("sleep() interrupted");
            }
        }

        public String toString() {
            return mThread.getName() + ": " + mCountDown;
        }
    }

    public InnerRunnable1(String name) {
        mInner = new Inner(name);
    }
}

/**
 * Using an anonymous Runnable implementation
 */
class InnerRunnable2 {
    private int mCountDown = 5;

    private Thread mThread;

    public InnerRunnable2(String name) {
        mThread = new Thread(new Runnable() {
            public void run() {
                try {
                    while(true) {
                        System.out.println(this);
                        if(--mCountDown == 0) {
                            return;
                        }
                        TimeUnit.MILLISECONDS.sleep(10);
                    }
                } catch(InterruptedException e) {
                    System.out.println("sleep() interrupted");
                }
            }

            public String toString() {
                return Thread.currentThread().getName() +
                       ": " + mCountDown;
            }
        }, name);

        mThread.start();
    }
}

/**
 * ThreadMethod类展示了在方法内部如何创建线程,而不是构造器
 * 如果该线程只执行辅助操作，而不是该类的重要操作，那么这与
 * 该类的构造器内部启动线程相比，可能是一种更加有用而合适的
 * 方式。
 */
class ThreadMethod {
    private int mCountDown = 5;

    private Thread mThread;

    private String mName;

    public ThreadMethod(String name) {
        mName = name;
    }

    public void runTask() {
        if(mThread == null) {
            mThread = new Thread(mName) {
                public void run() {
                    try {
                        while(true) {
                            System.out.println(this);
                            if(--mCountDown == 0) {
                                return;
                            }
                            sleep(10);
                        }
                    } catch(InterruptedException e) {
                        System.out.println("sleep() interrupted");
                    }
                }

                public String toString() {
                    return getName() + ": " + mCountDown;
                }
            };

            mThread.start();
        }
    }
}

/**
 * 编码的变体(三): 内部类隐藏线程
 */
public class ThreadVariations {
    public static void main(String[] args) {
        new InnerThread1("InnerThread1");
        new InnerThread2("InnerThread2");
        new InnerRunnable1("InnerRunnable1");
        new InnerRunnable2("InnerRunnable2");
        new ThreadMethod("ThreadMethod").runTask();
    }
}


